package com.example.diskfilesystem.directory;

import com.example.diskfilesystem.show.ShowAlert;
import config.Config;
import com.example.diskfilesystem.disk.Disk;
import com.example.diskfilesystem.disk.FATManager;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class DirectoryManager {
    private Disk disk;
    private FATManager fatManager;

    public DirectoryManager(Disk disk, FATManager fat) {
        this.disk = disk;
        this.fatManager = fat;
    }

    //读取指定目录块的8条目录项
    public List<DirectoryEntry> readDirectoryEntries(int dirBlock) throws IOException {
        byte[] data = disk.readBlock(dirBlock);
        if (data == null) {return null;}
        List<DirectoryEntry> list = new ArrayList<>();
        for (int i = 0; i < 8; i++) {
            byte[] entryData = new byte[8];
            System.arraycopy(data, i * 8, entryData, 0, 8);
            list.add(DirectoryEntry.fromBytes(entryData));
        }
        return list;
    }

    //将8条目录项写入指定目录块
    public void writeDirectoryEntries(int dirBlock, List<DirectoryEntry> entries) throws IOException {
        byte[] data = new byte[Config.BLOCK_SIZE];
        for (int i = 0; i < entries.size(); i++) {
            byte[] entryBytes = entries.get(i).toBytes();
            System.arraycopy(entryBytes, 0, data, i * 8, 8);
        }
        disk.writeBlock(dirBlock, data);
    }

    //新建目录（在指定目录块内新建一个目录项+分配空闲块）
    public boolean createDirectory(int parentBlock, String name) throws IOException {
        List<DirectoryEntry> entries = readDirectoryEntries(parentBlock);
        int freeSlot = -1;
        //读取父目录是否存在
        if (entries == null || entries.size() == 0) {
            System.out.println("父目录不存在！");
            return false;
        }
        //检查父目录是否是目录
//        byte[] parent = disk.readBlock(parentBlock);
//        if(parentBlock != 2) {
//            System.out.println("父目录不存在！");
//            return false;
//        }

        //查找空闲目录项
        for (int i = 0; i < entries.size(); i++) {
            if (entries.get(i).isEmpty()) {
                freeSlot = i;
                break;
            }
        }
        if (freeSlot == -1) {
            System.out.println("该目录已满！");
            return false;
        }

        //目录未满，则在磁盘空间中找寻空闲块
        int newBlock = fatManager.allocateBlock();
        //fatManager.printFAT(2,2);
        if (newBlock == -1) {
            //ShowAlert.showAlert("磁盘空间已满，创建目录失败！");
            System.out.println("磁盘空间已满，创建目录失败！");
            return false;
        }

        //找到空闲块，在目标目录中新建目录项
        DirectoryEntry newDir = new DirectoryEntry(name, "  ", DirectoryEntry.ATTR_dir, (byte) newBlock, (byte) 0);
        entries.set(freeSlot, newDir);

        writeDirectoryEntries(parentBlock, entries);

        //初始化新目录块为空目录
        byte[] rootBlock = new byte[Config.BLOCK_SIZE];
        for (int i = 0; i < Config.BLOCK_SIZE; i += 8) {
            rootBlock[i] = '$';  // '$'表示空目录项
        }
        disk.writeBlock(newBlock, rootBlock);
        return true;
    }

    //显示目录块的所有目录项
    public void showDirectory(int dirBlock) throws IOException {
        List<DirectoryEntry> entries = readDirectoryEntries(dirBlock);
        for (int i = 0; i < entries.size(); i++) {
            DirectoryEntry e = entries.get(i);
            if (!e.isEmpty()) {
                System.out.printf("[%d] %s %s start=%d len=%d attr=0x%02X\n",
                        i, e.getFileName(), e.getFileType(),
                        e.getStartBlock(), e.getLength(), e.getAttribute());
                //把目录展示在图形界面上 TODO
            }
        }
    }

    //删除掉空目录
    public boolean deleteDirectory(int parentBlock, String name) throws IOException {
        List<DirectoryEntry> entries = readDirectoryEntries(parentBlock);
        //寻找目标目录在父目录中的目录项
        for(int i=0;i<entries.size();i++){
            DirectoryEntry e = entries.get(i);

            //找到名字一样的目录项
            if(e.getFileName().equals(name) && e.getAttribute()==DirectoryEntry.ATTR_dir){
                int targetBlock = e.getStartBlock();
                entries = readDirectoryEntries(targetBlock);
                for(int j=0;j<entries.size();j++){
                    DirectoryEntry entry = entries.get(j);
                    if(!entry.isEmpty()){
                        //目标目录不为空
                        //System.out.println("目标目录不为空！");
                        return false;
                    }
                }
                //目标目录的8个目录项均为空
                //System.out.println("目标目录的8个目录项均为空！");
                //进行删除操作（父目录块内的对应目标目录项清空 + 目标目录块的64字节置0 + FAT表的对应块状态置0）
                e.setFileName("$\0\0");
                e.setFileType("\0\0");
                e.setAttribute((byte)0);
                e.setStartBlock((byte)0);
                e.setLength((byte)0);
                entries.remove(i);
                entries.add(i,e);
                writeDirectoryEntries(parentBlock,entries);

                disk.clearBlock(targetBlock);

                fatManager.freeChain(targetBlock);

                return true;
            }

        }
        //找不到目标目录
        //System.out.println("找不到目标目录！");
        return false;
    }




}